using System;
using System.Collections;
using System.Data;

using LocalBoard.Domain;

namespace LocalBoard.Persistence.MockAccessor
{
	public class MockProfile_x_PollMessage : IMockAccessor
	{
		private DataTable _profile_x_PollMessageTable = new DataTable("Profile_x_PollMessage");
		public static readonly MockProfile_x_PollMessage Instance = 
			new MockProfile_x_PollMessage();

		private MockProfile_x_PollMessage()
		{
			_profile_x_PollMessageTable.Columns.Add("Profile_Id", typeof(int));
			_profile_x_PollMessageTable.Columns.Add("Message_Id", typeof(int));
			_profile_x_PollMessageTable.Columns.Add("Point", typeof(int));
		}

		public void ResetDataTable()
		{
			_profile_x_PollMessageTable.Clear();
		}

		public void RemoveRows(int tableIndex, DataRow[] rows)
		{
			throw new NotImplementedException();
		}

		public DataRow[] ExecuteFilter(string filterExpression)
		{
			throw new NotImplementedException();
		}

		public void InsertVoteForMessage(int profileId, int messageId)
		{
			InsertVoteForMessage(profileId, messageId, 0);
		}

		public void InsertVoteForMessage(int profileId, int messageId, int point)
		{
			DataRow newRow = _profile_x_PollMessageTable.NewRow();
			newRow["Profile_Id"] = profileId;
			newRow["Message_Id"] = messageId;
			newRow["Point"] = point;

			_profile_x_PollMessageTable.Rows.Add(newRow);
		}

		/// <summary>
		/// Get list of votes for message
		/// </summary>
		/// <param name="messageId">Message id</param>
		/// <returns>List of <see cref="Vote">Vote</see>s</returns>
		public ArrayList GetVoteListByMessageId(int messageId)
		{
			ArrayList votes = new ArrayList();

			foreach(DataRow row in _profile_x_PollMessageTable.Select(string.Format("Message_Id = {0}", messageId)))
			{
				votes.Add(new Vote(DataConverter.GetInteger(row["Message_Id"]), DataConverter.GetInteger(row["Profile_Id"]), DataConverter.GetInteger(row["Point"])));
			}
			return votes;
		}

		public void DeleteVotersForPollMessage(int messageId)
		{
			DataRow[] targetRows = _profile_x_PollMessageTable.Select("Message_Id = " + messageId.ToString());
			for(int i=0; i<targetRows.Length; i++)
			{
				_profile_x_PollMessageTable.Rows.Remove(targetRows[i]);
				_profile_x_PollMessageTable.AcceptChanges();
			}
		}
	}
	/// <summary>
	/// Summary description for MockPollItemAccessor.
	/// </summary>
	public class MockPollItemAccessor : IPollItemAccessor, IMockAccessor
	{
		private int _oId = 0;
		private DataTable _pollItemTable = new DataTable("PollItem");
		private MockProfile_x_PollMessage _profile_x_pollMessage = MockProfile_x_PollMessage.Instance;

		public static readonly MockPollItemAccessor Instance = 
			new MockPollItemAccessor();

		private MockPollItemAccessor()
		{
			_pollItemTable.Columns.Add("Id", typeof(int));
			_pollItemTable.Columns.Add("Name", typeof(string));
			_pollItemTable.Columns.Add("Vote", typeof(int));
			_pollItemTable.Columns.Add("Message_Id", typeof(int));
		}

		public void ResetDataTable()
		{
			_oId = 0;
			_pollItemTable.Clear();
			_profile_x_pollMessage.ResetDataTable();
		}

		public void RemoveRows(int tableIndex, DataRow[] rows)
		{
			throw new NotImplementedException();
		}

		public DataRow[] ExecuteFilter(string filterExpression)
		{
			throw new NotImplementedException();
		}

		#region IPollItemAccessor Members

		public ArrayList GetPollItemListByMessageId(int messageId)
		{
			ArrayList pollItemList = new ArrayList();

			foreach(DataRow row in _pollItemTable.Select(string.Format("Message_Id={0}", messageId)))
			{
				pollItemList.Add(GetPollItemFromResultRow(row));
			}
			return pollItemList;
		}

		public int Insert(PollItem pollItem, int messageId)
		{
			_oId++;
			DataRow newRow = _pollItemTable.NewRow();
			
			newRow["Id"] = _oId;
			newRow["Name"] = pollItem.Name;
			newRow["Vote"] = pollItem.NumberOfVotes;
			newRow["Message_Id"] = messageId;

			_pollItemTable.Rows.Add(newRow);

			return _oId;
		}

		public void Delete(int id, int messageId)
		{
			if(this.GetVoterIdListByMessageId(messageId).Count == 0)
			{
				DataRow row = FindPollItemDataRow(id);
				if(row!=null)
				{
					_pollItemTable.Rows.Remove(row);
					_pollItemTable.AcceptChanges();
				}
			}
			else
				throw new Exception("You can not delete poll-items since a vote has already begun.");
		}	

		public void PostPoll(int id, int messageId, int profileId)
		{
			if(!GetVoterIdListByMessageId(messageId).Contains(profileId))
			{
				DataRow row = FindPollItemDataRow(id);
				if(row!=null)
				{
					row["Vote"] = DataConverter.GetInteger(row["Vote"]) + 1;
					_pollItemTable.AcceptChanges();
				}

				_profile_x_pollMessage.InsertVoteForMessage(profileId, messageId);
			}
		}

		public ArrayList GetVoterIdListByMessageId(int messageId)
		{
			ArrayList voterIdList = new ArrayList();
			foreach(Vote vote in _profile_x_pollMessage.GetVoteListByMessageId(messageId))
			{
				voterIdList.Add(vote.ProfileId);
			}
			return voterIdList;
		}

		public void DeleteVotersForPollMessage(int messageId)
		{
			_profile_x_pollMessage.DeleteVotersForPollMessage(messageId);
		}
		#endregion

		private DataRow FindPollItemDataRow(int id)
		{
			foreach(DataRow row in _pollItemTable.Rows)
			{
				if(DataConverter.GetInteger(row["Id"])==id)
					return row;
			}
			return null;
		}

		private PollItem GetPollItemFromResultRow(DataRow row)
		{
			return new PollItem(DataConverter.GetInteger(row["Id"]), DataConverter.GetString(row["Name"]), DataConverter.GetInteger(row["Vote"]));
		}
	}
}
